/**
 * @file 	 sq680.h
 * @brief
 * @author 	 wenbo
 * @version  1.0
 * @date 	 2022-02-11
 *
 * @copyright Copyright (c) 2022  YGL
 *
 */

#ifndef __SQ680_H
#define __SQ680_H

#include "../../bsp/bsp.h"

// 寄存器地址定义
/****************************************************************/
#define ADDR_RUN_MODE       0x0000      //F000 运行指令通道
#define ADDR_FREQ_SRC       0x0001      //F001 频率指令选择
#define ADDR_ACC_TIME       0x0005      //F005 加速时间
#define ADDR_DEC_TIME       0x0006      //F006 减速时间
#define ADDR_DI_S1_FUN      0x0020      //F032 S1端子功能选择
#define ADDR_DI_S2_FUN      0x0021      //F033 S2端子功能选择
#define ADDR_DI_S3_FUN      0x0022      //F034 S3端子功能选择
#define ADDR_DI_S4_FUN      0x0023      //F035 S4端子功能选择
#define ADDR_DI_S5_FUN      0x0024      //F036 S5端子功能选择
#define ADDR_FR_CTRL_MODE   0x0025      //F037 FWD/REV端子控制模式
#define ADDR_CTRL_REG       0x2000      //特殊寄存器 控制字寄存器
#define ADDR_TAR_FREQ       0x2001      //特殊寄存器 设定频率
#define ADDR_ERROR_CODE     0xE000      //特殊寄存器 故障代码
#define ADDR_CURRENT        0x0D06      //转矩电流 （不可用，资料无此寄存器值）


#define ADDR_STAGE_BASE     (0x002E)
#define ADDR_STAGE_SPEED_1  (ADDR_STAGE_BASE + 0)   //段速1
#define ADDR_STAGE_SPEED_2  (ADDR_STAGE_BASE + 5)   //段速2
#define ADDR_STAGE_SPEED_3  (ADDR_STAGE_BASE + 10)  //段速3
#define ADDR_STAGE_SPEED_4  (ADDR_STAGE_BASE + 15)  //段速4
#define ADDR_STAGE_SPEED_5  (ADDR_STAGE_BASE + 20)  //段速5
#define ADDR_STAGE_SPEED_6  (ADDR_STAGE_BASE + 25)  //段速6
#define ADDR_STAGE_SPEED_7  (ADDR_STAGE_BASE + 30)  //段速7



// 相关寄存器设定值枚举
/****************************************************************/
 // F000 运行指令通道
typedef enum {
    MODE_NONE = 0,          // 0: 不允许设置
    MODE_KEY,   	        // 1：键盘运行指令通道
    MODE_IO,                // 2：端子运行指令通道
    MODE_PON_AUTO,          // 3: 上电自动运行
    MODE_485,               // 4：通讯运行指令通道

    MODE_MAX,
}Type_sq680_Mode_Enum;

// F001 频率指令选择
typedef enum {
    F_SRC_NONE = 0,         // 0: 不允许设置
    F_SRC_KNOB,     	    // 1：面板电位器设定
    F_SRC_AI1,              // 2：模拟量AI1设定
    F_SRC_KEY,              // 3：键盘数字设定
    F_SRC_MODBUS,           // 4：MODBUS 通讯设定
    F_SRC_PLC,              // 5：简易PLC程序设定
    F_SRC_PID,              // 6：PID控制设定

    F_SRC_MAX,
}Type_sq680_F_Src_Enum;

// F037 FWD/REV端子控制模式
typedef enum {
    FR_MODE_1LINE_1 = 0,    // 0：单线模式1
    FR_MODE_1LINE_2,        // 1：单线模式2
    FR_MODE_2LINE_1,        // 2：两线模式1
    FR_MODE_2LINE_2,        // 3：两线模式2
    FR_MODE_3LINE_1,        // 4：三线模式1
    FR_MODE_3LINE_2,        // 5：三线模式2

    FR_MODE_MAX,
}Type_sq680_FR_Mode_Enum;

// X1 ~ X5 端子功能配置
typedef enum {
    DI_FUN_NONE = 0,        // 0: 控制端闲置
    DI_FUN_STAGE_1,         // 1: 多段速端子 1 
    DI_FUN_STAGE_2,         // 2: 多段速端子 2
    DI_FUN_STAGE_3,         // 3: 多段速端子 3 
    DI_FUN_SWITCH_FREQ,     // 4: 频率给定方式切换
    DI_FUN_FWD,             // 5: 正转运行
    DI_FUN_REV,             // 6: 反转运行 
    DI_FUN_JOG_F,           // 7: 正转点动 
    DI_FUN_JOG_R,           // 8: 反转点动
    DI_FUN_FREE_STOP,       // 9: 自由停车 
    DI_FUN_EERR_IN,         // 10: 外部故障输入
    DI_FUN_RECOVER,         // 11: 故障复位
    DI_FUN_3LINE,           // 12: 三线式运行控制
    DI_FUN_1LINE_OR_STOP,   // 13: 单线式运行或停机 
    DI_FUN_1LINE_DIRECT,    // 14: 单线式方向切换
    DI_FUN_1LINE_STOP,      // 15: 单线式停机
    DI_FUN_SUPPER_STOP,     // 16: 超级停机
    DI_FUN_1LINE_FWD,       // 17: 单线触发正转运行
    DI_FUN_1LINE_REV,       // 18: 单线触发反转运行
    DI_FUN_CMD_1,           // 19: 运行命令通道选择1
    DI_FUN_CMD_2,           // 20: 运行命令通道选择2 
    DI_FUN_FREQ_U,          // 21: 频率设定递增（UP） 
    DI_FUN_FREQ_D,          // 22: 频率设定递减（DOWN）
    DI_FUN_EMC_STOP,        // 23: 紧急停止
    DI_FUN_RESERV1,         // 24: 保留 
    DI_FUN_RESERV2,         // 25: 保留 
    DI_FUN_RESERV3,         // 26: 保留 
    DI_FUN_RESERV4,         // 27: 保留 

    DI_FUN_MAX,
}Type_sq680_DI_Fun_Enum;

// ctrl 特殊寄存器 控制字寄存器
typedef enum {
    CTRL_NONE = 0,          // 0：无效
    CTRL_FWD,               // 1：正转运行
    CTRL_REV,               // 2：反转运行
    CTRL_JOG_F,             // 3：正转点动
    CTRL_JOG_R,             // 4：反转点动
    CTRL_SLOW_STOP,         // 5：减速停机
    CTRL_FREE_STOP,         // 6：自由停机（紧急停机）
    CTRL_RECOVER,           // 7：故障复位
    CTRL_JOG_STOP,          // 8：点动停止

    CTRL_MAX,
}Type_sq680_Ctrl_Enum;

// error type 故障类型
typedef enum {
    ERR_NONE = 0,           // 0：无故障
    ERR_OCP_U,              // 1：加速过电压
    ERR_OCP_D,              // 2：减速过电压
    ERR_OCP_C,              // 3：恒速过电压
    ERR_OVP_U,              // 4：加速过电流
    ERR_OVP_D,              // 5：减速过电流
    ERR_OVP_C,              // 6：恒速过电流
    ERR_OVP_STOP,           // 7：停机时过电压
    ERR_RESV1,              // 8：保留
    ERR_INV_FAULT,          // 9：逆变模块异常
    ERR_OTP,                // 10：散热器过热
    ERR_OVERLOAD1,          // 11：变频器过载
    ERR_OVERLOAD2,          // 12：电机过载
    ERR_EXT,                // 13：外部设备故障
    ERR_485,                // 14：485通讯故障
    ERR_IcE,                // 15：电流检测故障
    ERR_SYS_NOISE,          // 16：系统干扰
    ERR_RUN_UV,             // 17：运行中欠压
    ERR_RESV2,              // 18：保留
    ERR_RESV3,              // 19：保留
    ERR_RESV4,              // 20：保留

    ERR_MAX,
}Type_sq680_Err_Enum;


// 变频器驱动结构
/****************************************************************/
// 485通信相关
typedef struct {
    uint8_t 	slave_id;    	            // modbus slave id
    uint8_t 	port;    		            // modbus uart port
    uint32_t 	speed;   		            // modbus uart speed
    uint8_t 	rec_data[20];               // modbus recive buffer
    uint8_t 	rec_len; 		            // modbus recive data length
}Type_sq680_Com_Def;

// sq680 结构
typedef struct
{
    bool                    isInitOk;       // 是否初始化
    bool                    isReverseDir;   // 是否反转旋转方向

    Type_sq680_Com_Def 	    com;            // 通信相关结构

    /* 记录上一次成功写入或读取变频器的数值 */
    Type_sq680_Mode_Enum    mode;           // 运行模式
    Type_sq680_F_Src_Enum   F_src;          // 频率源
    Type_sq680_Ctrl_Enum    ctrl;           // 控制寄存器
    Type_sq680_Err_Enum     errCode;        // 错误码

    int16_t                 stageTable[7];  // 段速值
    int16_t                 current;        // 当前电流（不可用，资料无此寄存器值）
    int16_t                 tar_freq;       // 目标频率
    uint16_t                accTime;        // 加速时间
    uint16_t                decTime;        // 减速时间

    Type_GPIO_Def           gpio_STF;       // X1 端子GPIO
    Type_GPIO_Def           gpio_STR;       // X2 端子GPIO
    Type_GPIO_Def           gpio_S0;        // X3 端子GPIO
    Type_GPIO_Def           gpio_S1;        // X4 端子GPIO
    Type_GPIO_Def           gpio_S2;        // X5 端子GPIO

}Type_sq680_Def;



// API 接口
/************************************************************************/
/**
 * @brief       初始化速驱变频器
 * @param[in]	pList               变频器列表
 * @param[in]	listLen             变频器列表长度
 * @return      bool                执行成功返回true
 */
extern bool xp_sq680_init(Type_sq680_Def* const pList, uint8_t listLen);

/**
 * @brief       驱动卸载
 * @return      bool                执行成功返回true
 */
extern bool xp_sq680_Deinit(void);



/************************************************************************/
/**
 * @brief       通过总线控制变频器运行
 * @param[in]	devId               变频器序号
 * @param[in]	freq                目标频率(0：减速停止，单位0.01Hz)
 * @return      bool                执行成功返回true
 */
extern bool xp_sq680_bus_run(int devId, int freq);

/**
 * @brief       通过IO控制变频器运行(会自动切换到IO控制模式)
 * @param[in]	devId               变频器序号
 * @param[in]	speed               段速(0：停止，-7 ~ 7)
 * @return      bool                执行成功返回true
 */
extern bool xp_sq680_io_run(uint8_t devId, int speed);



/************************************************************************/
/**
 * @brief       获取变频器错误码
 * @param[in]	devId               变频器序号
 * @param[out]	pResult             错误码结果
 * @return      bool                执行成功返回true
 */
extern bool xp_sq680_get_error_code(int devId, uint32_t* pResult);

/**
 * @brief       获取变频器电流（不可用，资料无此寄存器值）
 * @param[in]	devId               变频器序号
 * @param[out]	pResult             电流结果
 * @return      bool                执行成功返回true
 */
extern bool xp_sq680_get_current(int devId, int16_t* pResult);



/************************************************************************/
/**
 * @brief       清除驱动器错误
 * @param[in]	devId               变频器序号
 * @return      bool                执行成功返回true
 */
extern bool xp_sq680_clear_error(int devId);

/**
 * @brief       设置指定索引的段速值
 * @param[in]	devId               变频器索引id
 * @param[in]	stage_id            段速id
 * @param[in]	val                 段速目标值((单位0.01Hz))          
 * @return      bool                执行成功返回true
 */
extern bool xp_sq680_set_stage_speed(int devId, uint8_t stage_id, uint16_t val);

/**
 * @brief       设置指定索引的加速时间
 * @param[in]	devId               变频器索引id
 * @param[in]	time                加速时间（单位0.1s）
 * @return      bool                执行成功返回true
 */
extern bool xp_sq680_set_acc_time(int devId, uint16_t val);

/**
 * @brief       设置指定索引的减速时间
 * @param[in]	devId               变频器索引id
 * @param[in]	time                减速时间（单位0.1s）
 * @return      bool                执行成功返回true
 */
extern bool xp_sq680_set_dec_time(int devId, uint16_t val);


#endif